import { Injectable, HttpException } from '@nestjs/common';
// import { HttpException } from '@nestjs/core';
import { InjectRepository, InjectEntityManager } from '@nestjs/typeorm';
import { Repository, EntityManager, In } from 'typeorm';
import { Role } from "../../entities/role.entity";
import { Permission } from "../../entities/permission.entity";
import { responseStatus } from "../../utils";
// import { AuthService } from '../auth/auth.service';
@Injectable()
export class RoleService {
    constructor(
        @InjectEntityManager()
        private readonly entityManager: EntityManager,
        @InjectRepository(Role)
        private readonly roleRepository: Repository<Role>,
        @InjectRepository(Permission)
        private readonly permissionRepository: Repository<Permission>,
        // private readonly authService: AuthService
    ) { }
    async getAllRoles(data) {
        data.current = data.current || 1
        data.pageSize = data.pageSize || 10
        // 1. 准备工作：注入Repository，创建queryBuilder
        // 条件筛选和分页查询代码
        let queryBy = this.roleRepository.createQueryBuilder('role')
        // 2. 条件筛选查询，如名称、类型等，传入对应字段即可
        // .where(data as Partial<role>)
        const { current = 1, pageSize = 10, name } = data;

        if (name) {
            queryBy = queryBy.andWhere(`name LIKE :name`)
            .setParameter(`name`, `%${name}%`);
        }
        // 3. 时间范围筛选
        if (data && data['createTimeStart'] && data['createTimeEnd']) {
            queryBy = queryBy.andWhere('create_time BETWEEN :start AND :end', {
                start: data['createTimeStart'],
                end: data['createTimeEnd']
            })
        }

        // 普通排序
        queryBy = queryBy.orderBy('create_time', 'DESC')

        // 自定义条件，且多重排序
        // 例如：create_time字段为 ${data.start} 的优先显示,然后再在此基础上再进行时间和状态的排序
        queryBy = queryBy
            .addOrderBy('create_time', 'DESC')
        queryBy = queryBy
            .skip(pageSize * (current - 1))
            .take(pageSize)

        /* 其中限制获取的条数，用 take 和 limit 都可以，官方给出的文档说明
        take: 
            * Sets maximal number of entities to take.
        limit:     
            * Set's LIMIT - maximum number of rows to be selected.
            * NOTE that it may not work as you expect if you are using joins.
            * If you want to implement pagination, and you are having join in your query,
            * then use instead take method instead.
        因此限制返回条数的话，首先考虑使用take，limit 是 take 的功能子集
        */
        // 5. 获取结果及(非分页的)查询结果总数
        // 或使用 .getMany() 不会返回总数

        return await queryBy.getManyAndCount()
    }
    findRolesByIds (roleIds: number[]) {
        return this.entityManager.find('Role', {
            where: {
              id: In(roleIds)
            },
            relations: ['permissions']
        });
    }
    findRoleById (roleId: number) {
        return this.entityManager.findOne('Role', {
            where: {
              id: roleId
            } as Role,
            relations: ['permissions']
        });
    }
    async getMenu () {
      let queryBy = this.permissionRepository.createQueryBuilder('permission')
      let data = await queryBy.getMany()
      return data
    }
    async addOrUpdateRole(role: Role) {
        if (!role) {
            throw new HttpException("参数为空", responseStatus.failed.code);
        }
        let current = await this.roleRepository.findOne({ id: role.id })
        if (!current) {
            if (!role.name) throw new HttpException("角色名称不能为空！", responseStatus.failed.code);
            await this.roleRepository.save(role)
            return responseStatus.success.message
        } else {
            const updatedRole = { ...current, ...role }
            if (role.permissions && role.permissions.length) {
              let permissions = await this.entityManager.find('Permission', {
                where: {
                  code: In(role.permissions)
                } as any
              })
              updatedRole.permissions = permissions as Permission[]
            }
            await this.roleRepository.save(updatedRole)
            return responseStatus.success.message
        }
    }
    async delete(id) {
        if (!id) {
            throw new HttpException("参数为空", responseStatus.failed.code);
        }
        const hasrole = await this.roleRepository.findOne({ id })
        if (!hasrole) {
            throw new HttpException("角色不存在！", responseStatus.failed.code);
        } else {
            await this.roleRepository.remove(hasrole)
            return responseStatus.success.message
        }
    }
}